// server.ts - 简易静态文件服务器，支持端口自动检测和回调设置
import * as http from 'http'; // 引入 http 模块
import * as fs from 'fs'; // 引入文件系统模块
import * as path from 'path'; // 引入路径模块

class Server {
    private staticDir: string = ''; // 静态资源目录
    private closeCallback: (() => void) | null = null; // 关闭服务器时的回调
    private errorCallback: ((error: Error) => void) | null = null; // 错误回调
    private server: http.Server | null = null; // http 服务器实例
    private startCallback: ((port: number) => void) | null = null; // 启动服务器时的回调

    // 设置静态资源目录
    setStaticDir(dir: string) {
        this.staticDir = dir;
    }

    // 设置关闭服务器的回调
    setCloseCallback(callback: () => void) {
        this.closeCallback = callback;
    }

    // 设置错误回调
    setErrorCallback(callback: (error: Error) => void) {
        this.errorCallback = callback;
    }

    // 设置服务器启动时的回调
    setStartCallback(callback: (port: number) => void) {
        this.startCallback = callback;
    }

    // 启动服务器，自动检测可用端口
    async start(port?: number): Promise<number> {
        if (!this.staticDir) {
            throw new Error('Static directory not set');
        }
        // 自动检测可用端口
        const getAvailablePort = (start: number, end: number): Promise<number> => {
            return new Promise((resolve, reject) => {
                const tryPort = (p: number) => {
                    const tester = http.createServer();
                    tester.once('error', () => {
                        if (p < end) tryPort(p + 1);
                        else reject(new Error('No available port found'));
                    });
                    tester.once('listening', () => {
                        tester.close(() => resolve(p));
                    });
                    tester.listen(p);
                };
                tryPort(start);
            });
        };
        const actualPort = port ?? await getAvailablePort(3000, 3999);
        this.server = http.createServer((req, res) => {
            let reqPath = decodeURIComponent(req.url || '/');
            if (reqPath === '/') reqPath = '/index.html';
            const filePath = path.join(this.staticDir, reqPath);
            fs.stat(filePath, (err, stats) => {
                if (err || !stats.isFile()) {
                    res.statusCode = 404;
                    res.end('404 Not Found');
                    return;
                }
                fs.createReadStream(filePath).pipe(res);
            });
        });
        this.server.on('close', () => {
            if (this.closeCallback) this.closeCallback();
        });
        this.server.on('error', (err) => {
            if (this.errorCallback) this.errorCallback(err);
        });
        await new Promise<void>(resolve => this.server!.listen(actualPort, () => {
            if (this.startCallback) this.startCallback(actualPort);
            resolve();
        }));
        return actualPort;
    }

    // 可选：添加关闭方法
    close() {
        if (this.server) {
            this.server.close();
        }
    }
}

export default Server;